package com.keya.dicomtask;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ZipUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.net.HttpHeaders;
import com.keya.base.exception.BusinessException;
import com.keya.base.output.PageData;
import com.keya.base.output.ResultData;
import com.keya.device.GatewayProperties;
import com.keya.features.dicom.DicomFileUtils;
import com.keya.features.dicom.TagOptionInfo;
import com.keya.selector.SelectorResolver;
import com.keya.utils.CustomFileUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.io.File;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * dicom Task
 *
 * @author : xf.he
 * @version : 1.0 2023/11/2
 * @since : 1.0
 **/
@Slf4j
@RestController
@RequestMapping("dicom")
public class DicomTaskController {

    @Resource
    DicomTaskService dicomTaskService;
    @Resource
    TagOptionInfo tagOptionInfo;
    @Resource
    GatewayProperties gatewayProperties;


    @GetMapping("/list")
    public DicomTask list(Integer version) throws BusinessException {
        QueryWrapper<DicomTask> caseWrapper = new QueryWrapper<>();
        if (ObjectUtil.isNotEmpty(version)) {
            caseWrapper.gt("version", version);
        }
        caseWrapper.orderByAsc("version");
        caseWrapper.last(String.format("LIMIT %d", 1));
        return dicomTaskService.getOne(caseWrapper);
    }

    @GetMapping("/select")
    public PageData select(Integer offset, Integer limit,
                           @RequestParam(required = false, name = "selector") String selector) throws Exception {
        QueryWrapper<DicomTask> caseWrapper = SelectorResolver.getQueryWrapper(selector, DicomTask.class);
        caseWrapper.eq("mark", "0");
        caseWrapper.orderByAsc("version");
        if (offset != null && limit != null) {
            caseWrapper.last(String.format("LIMIT %d OFFSET %d", limit, offset));
        }
        List<DicomTask> dicomTasks = dicomTaskService.list(caseWrapper);
        return PageData.build(dicomTaskService.count(), dicomTasks);
    }

    @GetMapping("/download")
    public ResponseEntity<StreamingResponseBody> download(@NotBlank String aeTitle, @NotBlank String studyInstanceUID,
                                                          @RequestParam(name = "isDesensitize", defaultValue = "false") boolean isDesensitize) throws BusinessException {
        QueryWrapper<DicomTask> wrapper = new QueryWrapper<>();
        wrapper.eq("ae_title", aeTitle);
        wrapper.eq("studyInstanceUID", studyInstanceUID);
        return getStream(dicomTaskService.getOne(wrapper), isDesensitize);
    }

    @GetMapping("/download/{id}")
    public ResponseEntity<StreamingResponseBody> downloadById(@PathVariable String id,
                                                              @RequestParam(name = "isDesensitize", defaultValue = "false") boolean isDesensitize) throws BusinessException {
        return getStream(dicomTaskService.getById(id), isDesensitize);
    }


    @PostMapping("/upload")
    public ResultData upload(String aetitle,
                             @RequestPart("files") MultipartFile[] files) {
        return dicomTaskService.upload(aetitle, files);
    }


    public ResponseEntity<StreamingResponseBody> getStream(DicomTask one, boolean isDesensitize) {
        String targetFolder = gatewayProperties.getStorage() + "/tem/" + UUID.randomUUID();
        File file = new File(targetFolder);
        try {
            file.mkdirs();
            if (isDesensitize) {
                dicomDesensitize(one.getPath(), targetFolder);
            } else {
                File sourceFolder = new File(one.getPath());
                FileUtil.copy(sourceFolder, file, true);
            }
            String fileName = one.getStudyInstanceUID() + ".zip";
            String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
            StreamingResponseBody body = out -> {
                ZipUtil.zip(out, Charset.defaultCharset(), false, null, file);
                FileUtils.forceDelete(file);
            };
            return ResponseEntity.ok()
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName + "; filename*=UTF-8''" + encodedFileName)
                    .body(body);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    public void dicomDesensitize(String sourceFolder, String targetFolder) {
        List<File> fileList = new ArrayList<>();
        CustomFileUtils.traverseFolder(sourceFolder, fileList);
        for (File file : fileList) {
            DicomFileUtils.dicomDesensitize(file.getAbsolutePath(), targetFolder, tagOptionInfo);
        }
    }


}
